home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000…tember: Reference Library / Dev.CD Sep 00 RL Disk 1.toast / mac / Technical Documentation / Develop / develop Issue 28 / develop Issue 28 code / MacApp Debugging / TwistDownLists / UTwistDownControl.cp < prev    next >
Encoding:
Text File  |  1996-09-23  |  16.9 KB  |  558 lines  |  [TEXT/MPS ]

  1. //----------------------------------------------------------------------------------------
  2. // UTwistDownControl.cp
  3. // ETO20 MacApp 3.3.1, MPW 3.4.1
  4. // Copyright ©1994-1996 Conrad Kopala
  5. // Twist Down Lists version 2.0a0 7/15/96
  6. //----------------------------------------------------------------------------------------
  7.  
  8. #ifndef __UTWISTDOWNCONTROL__
  9. #include "UTwistDownControl.h"
  10. #endif
  11.  
  12. //The following is required for gAppleEventRouting
  13. #ifndef __UTWISTDOWNAPP__
  14. #include "UTwistDownApp.h"
  15. #endif
  16.  
  17. //The following is required for TTwistDownView in TExpandElementCommand::MakeAppleEvent 
  18. //and TCollapseElementCommand::MakeAppleEvent.
  19. #ifndef __UTWISTDOWNVIEW__
  20. #include "UTwistDownView.h"
  21. #endif
  22.  
  23. #ifndef __UTWISTDOWNDOCUMENT__
  24. #include "UTwistDownDocument.h"
  25. #endif
  26.  
  27. #ifndef __UTWISTDOWNELEMENT__
  28. #include "UTwistDownElement.h"
  29. #endif
  30.  
  31. #ifndef __UTWISTDOWNGLOBALS__
  32. #include "UTwistDownGlobals.h"
  33. #endif
  34.  
  35. //MacApp stuff
  36. //None
  37.  
  38. //ToolBox stuff
  39.  
  40. #ifndef __AEREGISTRY__
  41. #include "AERegistry.h"
  42. #endif
  43.  
  44. //ANSI stuff
  45. //None
  46. //========================================================================================
  47. // Global Procedures
  48. //========================================================================================
  49. #undef Inherited
  50.  
  51. //----------------------------------------------------------------------------------------
  52. // InitUTwistDownControl: 
  53. //----------------------------------------------------------------------------------------
  54. #pragma segment DlgInit
  55.  
  56. void InitUTwistDownControl()
  57. {
  58. MA_REGISTER_CLASS(TTwistDownControl);
  59. }
  60.  
  61. //========================================================================================
  62. // CLASS TTwistDownControl
  63. //========================================================================================
  64. #undef Inherited
  65. #define Inherited TControl
  66.  
  67. #pragma segment ARes
  68. MA_DEFINE_CLASS_M1(TTwistDownControl, Inherited);
  69. //----------------------------------------------------------------------------------------
  70. // TTwistDownControl constructor 
  71. //----------------------------------------------------------------------------------------
  72. #pragma segment ARes
  73. TTwistDownControl::TTwistDownControl()  
  74. {
  75. fTwistDownElement = NULL;
  76. fTwistDownDocument = NULL;
  77. fTwistDownView = NULL;
  78. fHiliteState = noHilite;
  79. fNewHiliteState = noHilite;
  80.  
  81. #if qDebug
  82. this -> PrintAppConstructorClassInfo();
  83. #endif
  84.  
  85. }
  86. //----------------------------------------------------------------------------------------
  87. // TTwistDownControl::~TTwistDownControl
  88. //----------------------------------------------------------------------------------------
  89. #pragma segment ARes
  90. TTwistDownControl::~TTwistDownControl()
  91. {
  92.  
  93. if (fTwistDownView)
  94.     fTwistDownView -> DecrementNumberOfControls();
  95.  
  96. if (fTwistDownElement)
  97.     fTwistDownElement -> SetTwistDownControlTo(NULL);
  98.     
  99. fTwistDownElement = NULL;
  100. fTwistDownDocument = NULL;
  101. fTwistDownView = NULL;
  102. fHiliteState = noHilite;
  103. fNewHiliteState = noHilite;
  104.  
  105. #if qDebug
  106. this -> PrintAppDestructorClassInfo();
  107. #endif
  108.  
  109. }
  110. //----------------------------------------------------------------------------------------
  111. // TTwistDownControl::ITwistDownControl: 
  112. //----------------------------------------------------------------------------------------
  113. #pragma segment ARes
  114. void TTwistDownControl::ITwistDownControl(VPoint& itsLocation, TTwistDownElement* itsTwistDownElement,
  115.                                                                 TTwistDownView* itsSuperView)
  116. {
  117. fIdentifier = kTwistDownControlViewID;    //Not really needed but useful when debugging
  118.                                                                                 //because it allows you to identify a twistDowncontrol.
  119. fTwistDownElement = itsTwistDownElement;
  120. fTwistDownView = itsSuperView;
  121.  
  122. VPoint itsSize = gZeroVPt;
  123.  
  124. if (fTwistDownView)
  125.     itsSize = fTwistDownView -> GetTwistDownControlSize();
  126.  
  127. TextStyle theTextStyle = gApplicationStyle;
  128.  
  129. if (itsSuperView)
  130.     theTextStyle = itsSuperView -> fTextStyle;
  131.     
  132. this -> IControl(itsSuperView,itsLocation, itsSize, sizeFixed, sizeFixed, theTextStyle);
  133.  
  134. fHandlesFirstClicks = FALSE;
  135.  
  136. fHelpID = kTwistDowncontrolHelp;
  137. fHelpIndex = 1;
  138.  
  139. if (fDocument)
  140.     {
  141.         fTwistDownDocument = (TTwistDownDocument*)fDocument;
  142.         
  143.         if (fTwistDownView)
  144.             {
  145.                 fTwistDownView -> IncrementNumberOfControls();
  146.         
  147.                 if (fTwistDownView -> ControlCountingEnabled() != TRUE)
  148.                     fTwistDownView -> IncrementInitialNumberOfControls();
  149.             }
  150.     }
  151.     
  152. }
  153. //----------------------------------------------------------------------------------------
  154. // TTwistDownControl::GetTwistDownElement:  
  155. //----------------------------------------------------------------------------------------
  156. #pragma segment ARes
  157. TTwistDownElement* TTwistDownControl::GetTwistDownElement()
  158. {
  159. return fTwistDownElement;
  160. }
  161. //----------------------------------------------------------------------------------------
  162. // TTwistDownControl::UpdateControlLocationTo:  called by TTwistDownView::UpdateTwistDownControlLocations
  163. //                                                                                                                TTwistDownDocument::UpdateTwistDownElements
  164. //----------------------------------------------------------------------------------------
  165. #pragma segment ARes
  166. void TTwistDownControl::UpdateControlLocationTo(short rowNumber)
  167. {
  168. VRect theVRect = gZeroVRect;
  169. VPoint twistDownControlLocation = gZeroVPt;
  170. Boolean itsFocus = FALSE;
  171.  
  172. fCoordinatesAreInvalid = TRUE;    //Doing this tells everybody that this twistDownControl
  173.                                                                 //needs to have its coordinates updated with a call to
  174.                                                                 //UpdateCoordinates()
  175.  
  176. short rowHeight = fTwistDownView -> GetRowHeight(1);    //This is safe because if there
  177.                                                                                                             //is a control there must be at
  178.                                                                                                             //least one row.
  179.  
  180. twistDownControlLocation.v = (long)(rowHeight*rowNumber - rowHeight);
  181. twistDownControlLocation.h = fTwistDownView -> fTwistDownControlLocation.h;
  182.  
  183. this -> SetLocationTo(twistDownControlLocation);
  184.  
  185. }
  186. //----------------------------------------------------------------------------------------
  187. // TTwistDownControl::UpdateControlSizeTo:  called by TTwistDownDocument::UpdateTwistDownElements
  188. //----------------------------------------------------------------------------------------
  189. #pragma segment ARes
  190. void TTwistDownControl::UpdateControlSizeTo()
  191. {
  192. fSize = fTwistDownView -> GetTwistDownControlSize();
  193. }
  194. //----------------------------------------------------------------------------------------
  195. // TTwistDownControl::SetLocationTo:  
  196. //----------------------------------------------------------------------------------------
  197. #pragma segment ARes
  198. void TTwistDownControl::SetLocationTo(VPoint& itsLocation)
  199. {
  200. fLocation.v = itsLocation.v;
  201. fLocation.h = itsLocation.h;
  202. }
  203. //----------------------------------------------------------------------------------------
  204. // TTwistDownControl::SuperViewChangedFrame: 
  205. //----------------------------------------------------------------------------------------
  206. #pragma segment MAViewNonRes
  207. void TTwistDownControl::SuperViewChangedFrame(const VRect& oldFrame,
  208.                                   const VRect& newFrame,Boolean invalidate)
  209. {
  210.  
  211. fLocation.h = fTwistDownView -> fTwistDownControlLocation.h;
  212.  
  213. Inherited::SuperViewChangedFrame(oldFrame,newFrame,invalidate);
  214.  
  215. }
  216. //----------------------------------------------------------------------------------------
  217. // TTwistDownControl::Draw:  
  218. //----------------------------------------------------------------------------------------
  219. #pragma segment MAViewRes
  220. void TTwistDownControl::Draw(const VRect& area)
  221. {
  222. #pragma unused area
  223.  
  224.     if (fTwistDownElement -> TestShowSubListFlag())
  225.         this -> DrawOpenTriangle();
  226.     else
  227.         this -> DrawClosedTriangle();
  228. }
  229. //----------------------------------------------------------------------------------------
  230. // TTwistDownControl::DoMouseUp: 
  231. //----------------------------------------------------------------------------------------
  232. #pragma segment ASelCommand
  233. void TTwistDownControl::DoMouseUp(VPoint& theMouse, TToolboxEvent* event, CPoint hysteresis)
  234. {
  235. #pragma unused hysteresis
  236. TExpandElementCommand* anExpandElementCommand = NULL;
  237. TCollapseElementCommand* aCollapseElementCommand = NULL;
  238.  
  239. //swallow a mouseUp event following a first click mouseDown event
  240. if (fTwistDownView -> fIsFirstClick == FALSE)
  241. {
  242. if (this -> ContainsMouse(theMouse) && event -> fIdentifier == mouseUp && this -> IsEnabled())
  243.     {
  244.         TTwistDownElement* targetElement = this -> GetTwistDownElement();
  245.         
  246.         if (targetElement -> TestHasSubListFlag())    //Make sure it is a folder. This is overkill because
  247.                                                                                                 //if we get here it has to be a folder.
  248.             {
  249.                 if (!targetElement -> TestShowSubListFlag())    //Make sure it isn't already expanded. This
  250.                                                                                                             //test determines whether we're expanding 
  251.                                                                                                             //or collapsing.
  252.                     {
  253.                         if (targetElement -> CouldExpandElement())    //Make sure expanding won't exceed the
  254.                                                                                                                         //capacity of TTextListView
  255.                             {
  256.                                 anExpandElementCommand = new TExpandElementCommand;
  257.                                 anExpandElementCommand -> IExpandElementCommand(fTwistDownDocument, targetElement);
  258.                                 if (gSendAppleEvents)
  259.                                     anExpandElementCommand -> fUseAppleEvent = TRUE;
  260.                                 this -> PostCommand(anExpandElementCommand);
  261.                             }
  262.                         else
  263.                             {
  264.                                 CStr63 theDisplayedText;
  265.                                 targetElement -> GetDisplayedText(theDisplayedText);
  266.                                 gErrorParm3 = theDisplayedText;
  267.                                 FailOSErr(errCantExpandElement);    //I need to make it put up a different alert.
  268.                             }
  269.                     }
  270.                 else
  271.                     {
  272.                     //Because we don't want this to fail for out of memory reasons,
  273.                     //allocate it from temporary memory.    //PGMacApp 550
  274.                         Boolean oldTemp = TemporaryAllocation(TRUE);
  275.                         Boolean oldArrayPerm = AllocateObjectsFromPerm(FALSE);                        
  276.                             aCollapseElementCommand = new TCollapseElementCommand;
  277.                             aCollapseElementCommand -> ICollapseElementCommand(fTwistDownDocument, targetElement);
  278.                             if (gSendAppleEvents)
  279.                                 aCollapseElementCommand -> fUseAppleEvent = TRUE;
  280.                             this -> PostCommand(aCollapseElementCommand);
  281.                         oldArrayPerm = AllocateObjectsFromPerm(oldArrayPerm);
  282.                         oldTemp = TemporaryAllocation(oldTemp);
  283.                     }
  284.             }    //end if (fTwistDownElement -> TestHasSubListFlag())
  285.     }
  286. }
  287.  
  288. }
  289. //----------------------------------------------------------------------------------------
  290. // TTwistDownControl::DoEvent: 
  291. //----------------------------------------------------------------------------------------
  292. #pragma segment MAControlRes
  293. void TTwistDownControl::DoEvent(EventNumber eventNumber, TEventHandler* source, TEvent* event)        
  294. {
  295.  
  296.  
  297.     switch (eventNumber)
  298.     {
  299.         case mExpandElement:
  300.             {
  301.                 this -> DrawIntermediateTriangle();
  302.                 fNewHiliteState = noHilite;
  303.                 this -> DrawOpenTriangle();
  304.             }
  305.             break;
  306.             
  307.         case mCollapseElement:
  308.             {
  309.                 this -> DrawIntermediateTriangle();
  310.                 fNewHiliteState = noHilite;
  311.                 this -> DrawClosedTriangle();                
  312.             }
  313.             break;
  314.         
  315.         case mTurnOff:
  316.             {
  317.                 fNewHiliteState = noHilite;
  318.                 this -> ForceRedraw();
  319.             }
  320.             break;
  321.             
  322.         default:
  323.             Inherited::DoEvent(eventNumber, source, event);
  324.             break;
  325.             
  326.     }    //end switch (eventNumber)
  327.         
  328. }
  329. //----------------------------------------------------------------------------------------
  330. // TTwistDownControl::Hilite:
  331. //----------------------------------------------------------------------------------------
  332. #pragma segment MAControlRes
  333. void TTwistDownControl::Hilite()
  334. {
  335.     VRect area;
  336.     CRect qdArea;
  337.  
  338. #if qDebug
  339.     this -> AssumeFocused();
  340. #endif
  341.  
  342.     switch (fNewHiliteState)
  343.         {
  344.                         
  345.             case blackHilite:
  346.                 {
  347.                 this -> FillTriangleBlack();
  348.                 }
  349.                 break;
  350.                                 
  351.             case whiteHilite:
  352.                 {
  353.                 this -> FillTriangleWhite();
  354.                 }
  355.                 break;
  356.                 
  357.             case noHilite:
  358.                 {
  359.                 //This could be the default case, but I think it is a little clearer written
  360.                 //explicitly as a case. At least this way, the casual reader knows the case
  361.                 //has been accounted for.
  362.                 }
  363.                 break;                
  364.                 
  365.         }
  366. }
  367. //----------------------------------------------------------------------------------------
  368. // TTwistDownControl::HiliteState:
  369. //----------------------------------------------------------------------------------------
  370. #pragma segment MAControlNonRes
  371. void TTwistDownControl::HiliteState(Boolean state, Boolean redraw)
  372. {
  373.     if (state != fHilite)
  374.     {
  375.         fHilite = state;
  376.         if (state)                                // hilite adorner draws the hilite state
  377.             {
  378.             fNewHiliteState = blackHilite;
  379.             }
  380.         else
  381.             {
  382.             fNewHiliteState = whiteHilite;
  383.             }
  384.  
  385.         if (redraw && this -> IsDrawable())
  386.             {
  387.             this -> Hilite();
  388.             }
  389.     }
  390. }
  391. //----------------------------------------------------------------------------------------
  392. // TTwistDownControl::TrackMouse: 
  393. //----------------------------------------------------------------------------------------
  394. #pragma segment ASelCommand
  395. void TTwistDownControl::TrackMouse(TrackPhase aTrackPhase,
  396.                           VPoint&  anchorPoint, VPoint& previousPoint, VPoint& nextPoint,
  397.                           Boolean mouseDidMove)
  398. {
  399. #pragma unused anchorPoint
  400. #pragma unused previousPoint
  401. #pragma unused mouseDidMove
  402. switch (aTrackPhase)
  403.     {
  404.         case trackBegin:
  405.             {
  406.             this -> HiliteState(TRUE, kRedraw);
  407.             }
  408.             break;
  409.             
  410.         case trackContinue:
  411.             {
  412.             this -> HiliteState(this->ContainsMouse(nextPoint), kRedraw);
  413.             }
  414.             break;
  415.  
  416.         case trackEnd:
  417.             {
  418.                 fHilite = FALSE;
  419.                 if (this->ContainsMouse(nextPoint))
  420.                     {
  421.                         if (fTwistDownElement -> TestHasSubListFlag())
  422.                             {
  423.                                  if (!fTwistDownElement -> TestShowSubListFlag())
  424.                                     this -> HandleEvent(mExpandElement,this,NULL);
  425.                                 else 
  426.                                     this -> HandleEvent(mCollapseElement,this,NULL);
  427.                             }
  428.                         }
  429.                         
  430.                 else
  431.                     {
  432.                         this -> HandleEvent(mTurnOff,this,NULL);                    
  433.                     }
  434.  
  435.             }    //end case trackEnd
  436.             
  437.             break;
  438.     }
  439.  
  440. }
  441. //----------------------------------------------------------------------------------------
  442. // TTwistDownControl::FillTriangleBlack: 
  443. //----------------------------------------------------------------------------------------
  444. #pragma segment MAControlRes
  445. void TTwistDownControl::FillTriangleBlack()
  446. {
  447. PolyHandle theTriangle = NULL;
  448.  
  449.     if (fTwistDownElement -> TestShowSubListFlag())
  450.         {
  451.             theTriangle = fTwistDownView -> GetOpenTriangle();
  452.             FillPoly(theTriangle, &qd.black);
  453.             FramePoly(theTriangle);
  454.         }
  455.     else
  456.         {
  457.             theTriangle = fTwistDownView -> GetClosedTriangle();
  458.             FillPoly(theTriangle, &qd.black);
  459.             FramePoly(theTriangle);
  460.         }
  461.         
  462. }
  463. //----------------------------------------------------------------------------------------
  464. // TTwistDownControl::FillTriangleGray: 
  465. //----------------------------------------------------------------------------------------
  466. #pragma segment MAControlRes
  467. void TTwistDownControl::FillTriangleGray()
  468. {
  469. PolyHandle theTriangle = NULL;
  470.  
  471.     if (fTwistDownElement -> TestShowSubListFlag())
  472.         {
  473.             theTriangle = fTwistDownView -> GetOpenTriangle();
  474.             FillPoly(theTriangle, &qd.ltGray);
  475.             FramePoly(theTriangle);
  476.         }
  477.     else
  478.         {
  479.             theTriangle = fTwistDownView -> GetClosedTriangle();
  480.             FillPoly(theTriangle, &qd.white);
  481.             FramePoly(theTriangle);
  482.         }
  483. }
  484. //----------------------------------------------------------------------------------------
  485. // TTwistDownControl::FillTriangleWhite: 
  486. //----------------------------------------------------------------------------------------
  487. #pragma segment MAControlRes
  488. void TTwistDownControl::FillTriangleWhite()
  489. {
  490. PolyHandle theTriangle = NULL;
  491.  
  492.     if (fTwistDownElement -> TestShowSubListFlag())
  493.         {
  494.             theTriangle = fTwistDownView -> GetOpenTriangle();
  495.             FillPoly(theTriangle, &qd.white);
  496.             FramePoly(theTriangle);
  497.         }
  498.     else
  499.         {
  500.             theTriangle = fTwistDownView -> GetClosedTriangle();
  501.             FillPoly(theTriangle, &qd.white);
  502.             FramePoly(theTriangle);
  503.         }
  504. }
  505. //----------------------------------------------------------------------------------------
  506. // TTwistDownControl::EraseControlArea: 
  507. //----------------------------------------------------------------------------------------
  508. #pragma segment MAControlRes
  509. void TTwistDownControl::EraseControlArea()
  510. {
  511.     VRect area;
  512.     CRect qdArea;
  513.  
  514. #if qDebug
  515.     this -> AssumeFocused();
  516. #endif
  517.     this -> ControlArea(area);
  518.     this -> ViewToQDRect(area, qdArea);
  519.     EraseRect(qdArea);    
  520. }
  521. //----------------------------------------------------------------------------------------
  522. // TTwistDownControl::DrawClosedTriangle: 
  523. //----------------------------------------------------------------------------------------
  524. #pragma segment MAViewRes
  525. void TTwistDownControl::DrawClosedTriangle()
  526. {
  527. PolyHandle theTriangle = fTwistDownView -> GetClosedTriangle();
  528. FillPoly(theTriangle, &qd.ltGray);
  529. FramePoly(theTriangle);
  530. }
  531. //----------------------------------------------------------------------------------------
  532. // TTwistDownControl::DrawOpenTriangle: 
  533. //----------------------------------------------------------------------------------------
  534. #pragma segment MAViewRes
  535. void TTwistDownControl::DrawOpenTriangle()
  536. {
  537. PolyHandle theTriangle = fTwistDownView -> GetOpenTriangle();
  538. FillPoly(theTriangle, &qd.ltGray);
  539. FramePoly(theTriangle);
  540. }
  541. //----------------------------------------------------------------------------------------
  542. // TTwistDownControl::DrawIntermediateTriangle: 
  543. //----------------------------------------------------------------------------------------
  544. #pragma segment MAViewRes
  545. void TTwistDownControl::DrawIntermediateTriangle()
  546. {
  547. long dontCare;
  548.  
  549. this -> EraseControlArea();
  550.     
  551. PolyHandle theTriangle = fTwistDownView -> GetIntermediateTriangle();
  552. FillPoly(theTriangle, &qd.black);
  553. FramePoly(theTriangle);    
  554. Delay(8, &dontCare);
  555. this -> EraseControlArea();    
  556. }
  557.  
  558. #pragma segment Inline